# ！/usr/bin/ python3
# -*- codeing = utf-8 -*-
# @Time :2022/1/5 11:54
# @Author:wuhha
# @File : consumer.py
# @Software: PyCharm
# 由于不能使用asgi上线，此文件里的代码不使用
import json
from functools import wraps

from channels.generic.websocket import AsyncWebsocketConsumer

from youpu.models import User


class MessagesConsumer(AsyncWebsocketConsumer):
    """处理私信应用中WebSocket请求"""

    # 为了让装饰器获得self的值，将装饰器和被装饰方法写在同一个类里
    def youpu_login_required_forconsumer(consumer_method):
        @wraps(consumer_method)
        async def inner(self, *args, **kwargs):
            # 根据session中携带的信息查出user【能够进入发送私信界面，说明一定已经登录了】
            username = self.scope["session"].get('uname', "")
            # 根据username查出user放到request中
            self.scope["user"] = User.objects.get(username=username)
            result = await consumer_method(self, *args, **kwargs)
            return result
        return inner

    @youpu_login_required_forconsumer#借助 method_decorator 将函数装饰器转换成方法装饰器
    async def connect(self):
        if self.scope['user'].is_anonymous:
            # 未登录的用户拒绝连接
            await self.close()
        else:
            await self.channel_layer.group_add(self.scope['user'].username, self.channel_name)
            await self.accept()

    @youpu_login_required_forconsumer
    async def receive(self, text_data=None, bytes_data=None):
        """接收私信"""
        await self.send(text_data=json.dumps(text_data))

    @youpu_login_required_forconsumer
    async def disconnect(self, code):
        """离开聊天组"""
        await self.channel_layer.group_discard(self.scope['user'].username, self.channel_name)


class NotificationsConsumer(AsyncWebsocketConsumer):
    """处理通知应用中的WebSocket请求"""

    def youpu_login_required_forconsumer(consumer_method):
        @wraps(consumer_method)
        async def inner(self, *args, **kwargs):
            # 根据session中携带的信息查出user【能够进入发送私信界面，说明一定已经登录了】
            username = self.scope["session"].get('uname', "")
            # 根据username查出user放到request中
            self.scope["user"] = User.objects.get(username=username)
            result = await consumer_method(self, *args, **kwargs)
            return result
        return inner

    @youpu_login_required_forconsumer
    async def connect(self):
        """建立连接"""
        if self.scope['user'].is_anonymous:
            # 未登录用户拒绝连接
            await self.close()
        else:
            await self.channel_layer.group_add('notifications', self.channel_name)
            await self.accept()

    @youpu_login_required_forconsumer
    async def receive(self, text_data=None, bytes_data=None):
        """将接收到的消息返回给前端"""
        await self.send(text_data=json.dumps(text_data))

    @youpu_login_required_forconsumer
    async def disconnect(self, code):
        """断开连接"""
        await self.channel_layer.group_discard('notifications', self.channel_name)
